/**
 * This file is part of 1genia trampoline
 * Copyright (C) 2007 - 2008 1genia (contact@1genia.com)
 *
 * This library is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; version 3 of the License. 
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Library General Public License for more details. 
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; see the file COPYING.TXT.  If not,
 * write to the Free Software Foundation, Inc., 51 Franklin Street,
 * Fifth Floor, Boston, MA 02110-1301, USA. 
 **/
package com.genia.toolbox.web.taglib.head;

import java.util.Set;
import java.util.TreeSet;

import com.genia.toolbox.basics.exception.technical.TechnicalException;
import com.genia.toolbox.web.taglib.head.css.CssLink;
import com.genia.toolbox.web.taglib.head.css.CssLinkContainer;
import com.genia.toolbox.web.taglib.head.js.JsFunctionContainer;
import com.genia.toolbox.web.taglib.head.js.JsScript;
import com.genia.toolbox.web.taglib.head.js.JsScriptContainer;
import com.genia.toolbox.web.taglib.head.title.Title;
import com.genia.toolbox.web.taglib.head.title.TitleContainer;

/**
 * Class that contain the information necessary to display the head.
 */
public class HeadContainer
    implements CssLinkContainer, TitleContainer, JsScriptContainer
{

  /**
   * {@link JsFunctionContainer} for onload.
   */
  private JsFunctionContainer initJsFunctionContainer;

  /**
   * {@link JsFunctionContainer} for onunload.
   */
  private JsFunctionContainer tearDownJsFunctionContainer;

  /**
   * the {@link Set} of {@link CssLink} to use.
   */
  private transient final Set<CssLink> cssLinks = new TreeSet<CssLink>();

  /**
   * the {@link Set} of {@link JsScript} to use.
   */
  private transient final Set<JsScript> jsScripts = new TreeSet<JsScript>();

  /**
   * the {@link Set} of {@link Title} to use.
   */
  private transient final Set<Title> titlesContainer = new TreeSet<Title>();



  /**
   * add a new css lin with its link, urlManager and priority.
   * 
   * @param link
   *          the link of the css to add
   * @param media
   *          the media of the css
   * @param urlManagerName
   *          the name of the urlManager
   * @param priority
   *          the priority of the css
   */
  public void addLink(final String link, final String media, final String urlManagerName, int priority)
  {
    if (media != null) {
      for (String subMedia : media.split(",")) {
        cssLinks.add(new CssLink(link, subMedia, urlManagerName, priority));
      }
    }
    else {
      cssLinks.add(new CssLink(link, null, urlManagerName, priority));
    }
  }



  /**
   * returns the set of <code>CssLink</code>.
   * 
   * @return the set of <code>CssLink</code>
   */
  public Set<CssLink> getLinks()
  {
    return cssLinks;
  }



  /**
   * returns the set of {@link JsScript}s.
   * 
   * @return the set of {@link JsScript}s
   */
  public Set<JsScript> getScripts()
  {
    return jsScripts;
  }



  /**
   * add a new title with its priority.
   * 
   * @param text
   *          the text of the title to add
   * @param priority
   *          the priority of the title to add
   * @throws TechnicalException
   *           a title with the same priority already exist
   */
  public void addTitle(final String text, final int priority)
      throws TechnicalException
  {
    final Title title = new Title(text, priority);
    if (titlesContainer.contains(title)) {
      throw new TechnicalException("A Title with the same priority [ " + priority + "] already exist", "");
    }
    titlesContainer.add(title);
  }



  /**
   * returns the unique Title.
   * 
   * @return the <code>Title</code>
   */
  public Title getTitle()
  {
    Title retour = null;
    if (!titlesContainer.isEmpty()) {
      retour = titlesContainer.iterator().next();
    }

    return retour;

  }



  /**
   * getter for the initJsFunctionContainer property.
   * 
   * @return the initJsFunctionContainer
   */
  public JsFunctionContainer getInitJsFunctionContainer()
  {
    return initJsFunctionContainer;
  }



  /**
   * getter for the tearDownJsFunctionContainer property.
   * 
   * @return the tearDownJsFunctionContainer
   */
  public JsFunctionContainer getTearDownJsFunctionContainer()
  {
    return tearDownJsFunctionContainer;
  }



  /**
   * setter for the initJsFunctionContainer property.
   * 
   * @param initJsFunctionContainer
   *          the initJsFunctionContainer to set
   */
  public void setInitJsFunctionContainer(JsFunctionContainer initJsFunctionContainer)
  {
    this.initJsFunctionContainer = initJsFunctionContainer;
  }



  /**
   * setter for the tearDownJsFunctionContainer property.
   * 
   * @param tearDownJsFunctionContainer
   *          the tearDownJsFunctionContainer to set
   */
  public void setTearDownJsFunctionContainer(JsFunctionContainer tearDownJsFunctionContainer)
  {
    this.tearDownJsFunctionContainer = tearDownJsFunctionContainer;
  }



  /**
   * /** add a new js script with its src, caching policy, urlManager and
   * priority.
   * 
   * @param src
   *          the src link
   * @param urlManagerName
   *          spring name where to get the UrlManager
   * @param cache
   *          whether the link is cachable
   * @param priority
   *          the priority of the script link
   * @see com.genia.toolbox.web.taglib.head.js.JsScriptContainer#addScript(java.lang.String,
   *      java.lang.String, boolean, int)
   */
  public void addScript(String src, String urlManagerName, boolean cache, int priority)
  {
    getScripts().add(new JsScript(src, urlManagerName, cache, priority));
  }

}
